package com.kevin.service.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.kevin.common.enums.DictSourceEnum;
import com.kevin.common.exception.BusinessException;
import com.kevin.service.entity.SysDictData;
import com.kevin.service.entity.SysDictType;
import com.kevin.service.mapper.SysDictDataMapper;
import com.kevin.service.mapper.SysDictTypeMapper;
import com.kevin.service.service.SysDictTypeService;
import com.kevin.service.vo.SysDictVO;
import com.fhs.trans.service.impl.DictionaryTransService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * 字典类型(SysDictType)表服务实现类
 *
 * @author makejava
 * @since 2023-03-27 14:44:09
 */
@Service
@RequiredArgsConstructor
public class SysDictTypeServiceImpl extends ServiceImpl<SysDictTypeMapper, SysDictType> implements SysDictTypeService, InitializingBean {
    private final SysDictDataMapper sysDictDataDao;
    private final DictionaryTransService dictionaryTransService;

    @Override
    public List<SysDictVO.DictData> getDictSql(Long id) {
        SysDictType entity = this.getById(id);
        try {
            return sysDictDataDao.getListForSql(entity.getDictSql());
        } catch (Exception e) {
            throw new BusinessException("动态SQL执行失败，请检查SQL是否正确！");
        }
    }

    @Override
    public List<SysDictVO> getDictList() {
        // 全部字典类型列表
        List<SysDictType> typeList = this.list(Wrappers.emptyWrapper());

        // 全部字典数据列表
        QueryWrapper<SysDictData> query = new QueryWrapper<SysDictData>().orderByAsc("sort");
        List<SysDictData> dataList = sysDictDataDao.selectList(query);

        // 全部字典列表
        List<SysDictVO> dictList = new ArrayList<>(typeList.size());
        for (SysDictType type : typeList) {
            SysDictVO dict = new SysDictVO();
            dict.setDictType(type.getDictType());

            for (SysDictData data : dataList) {
                if (type.getId().equals(data.getDictTypeId())) {
                    dict.getDataList().add(new SysDictVO.DictData(data.getDictLabel(), data.getDictValue(), data.getLabelClass()));
                }
            }

            // 数据来源动态SQL
            if (type.getDictSource() == DictSourceEnum.SQL.getValue()) {
                // 增加动态列表
                String sql = type.getDictSql();
                try {
                    dict.setDataList(sysDictDataDao.getListForSql(sql));
                } catch (Exception e) {
                    log.error("增加动态字典异常: type=" + type, e);
                }
            }

            dictList.add(dict);
        }

        return dictList;
    }

    @Override
    public void afterPropertiesSet() {
        refreshTransCache();
    }

    public void refreshTransCache() {
        // 异步不阻塞主线程，不会 增加启动用时
        CompletableFuture.supplyAsync(() -> {
            // 获取所有的字典项数据
            List<SysDictData> dataList = sysDictDataDao.selectList(new LambdaQueryWrapper<>());
            // 根据类型分组
            Map<Long, List<SysDictData>> dictTypeDataMap = dataList.stream().collect(Collectors
                    .groupingBy(SysDictData::getDictTypeId));
            List<SysDictType> dictTypeEntities = super.list();
            for (SysDictType dictTypeEntity : dictTypeEntities) {
                if (dictTypeDataMap.containsKey(dictTypeEntity.getId())) {
                    dictionaryTransService.refreshCache(dictTypeEntity.getDictType(), dictTypeDataMap.get(dictTypeEntity.getId())
                            .stream().collect(Collectors.toMap(SysDictData::getDictValue, SysDictData::getDictLabel)));
                }
            }
            return null;
        });
    }

}

